﻿using System;
using System.Collections.Generic;

namespace _23csharp隐藏方法和虚方法
{
    class Program
    {
        static void Main(string[] args)
        {
            Student student = new Student("张三",8);
            student.Walk();
            student.Eat();
            student.Say();

            Console.WriteLine("------------ 分割 ------------");
            Person stu = new Student("wangwu",15);
            stu.Walk();
            stu.Eat();

            
            Worker worker = new Worker();
            Console.WriteLine("------------ 分割 ------------");
            List<Person> ps = new List<Person>();
            ps.Add(student);
            ps.Add(worker);
            foreach (var item in ps)
            {
                item.Eat();
            }

            //Worker worker = new Worker();
            //worker.Walk();
            //worker.Eat();
        }
    }

    // 虚方法：virtual  关键字修饰的一个方法
    // virtual ： 虚拟的，虚构的，不真实的
    // 用于标记一个方法不真实，别人封装的方法里面的内容固化的，但virtual 修饰的却是虚晃一枪后面可以反悔的。
    // 隐藏方法： new ，新 ，新建
    // new 修饰的方法，可以从上往下调用（类似于功能的补充）
    // override 修饰的方法，可以从上往下调（类似于功能的补充），也可以从基类唤起 （out ref）


    public class Person
    {
        public int age;
        public Person()
        {
            this.age = default;
        }

        public Person(int age)
        {
            this.age = age;
        }
        //internal 、public
        public  void Say() 
        {
            Console.WriteLine("SAY");
        }
        // 虚方法
        // 人类的走路行为
        public virtual void Walk()
        {
            Console.WriteLine("Inside Person walk");
        }

        public void Eat() 
        {
            Console.WriteLine("Inside person eat......");
        }
    }

    public class Student : Person
    {
        public string name;
        public Student(string name, int age) : base(age)
        {
            this.name = name;
        }

        // override ：覆写，用于替换(隐藏)/补充 虚方法内的逻辑
        public override void Walk()
        {
            Console.WriteLine("Inside Student Walk");
            // base.Walk() 是调用 基类中的 Walk 逻辑
            //如果是替换逻辑，这句话干掉，不执行 Walk
            // 如果是补充方法的逻辑，这句话不能干掉，而且还可以随意穿插在你的逻辑中
            //base.Walk(); 

            //Console.WriteLine("Inside Student Walk ");
            if (age > 18)
            {
                base.Walk(); //假装回忆青春，小时候怎么怎么走的
                Console.WriteLine("是大学生");
            }
        }

        public new void Eat()
        {
            Console.WriteLine("Inside Student eat....");
            base.Eat();
        }
    }

    public class Worker : Person 
    {
 
        public override void Walk()
        {
            Console.WriteLine("工人走路");
        }

        public new void Eat()
        {
            Console.WriteLine("Inside 工人 eat....");
            base.Eat();
        }
    }

}
